home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -in_the_mag- / emulation / amiga / uae-0.7.0b2 / src / od-win32 / parser.c < prev    next >
C/C++ Source or Header  |  1998-01-20  |  7KB  |  291 lines

  1. /* 
  2.  * UAE - The Un*x Amiga Emulator
  3.  *
  4.  * Not a parser, but parallel and serial emulation for Win32
  5.  *
  6.  * Copyright 1997 Mathias Ortmann
  7.  */
  8.  
  9. #ifdef __GNUC__
  10. #define __int64 long long
  11. #include "machdep/winstuff.h"
  12. #else
  13. #include <windows.h>
  14. #include <ddraw.h>
  15. #include <stdlib.h>
  16. #include <stdarg.h>
  17. #include <commctrl.h>
  18. #include <commdlg.h>
  19. #include <stdio.h>
  20. #include <fcntl.h>
  21. #include <sys/stat.h>
  22. #include <io.h>
  23. #endif
  24.  
  25. #include "config.h"
  26. #include "sysconfig.h"
  27. #include "sysdeps.h"
  28.  
  29. #include "options.h"
  30. #include "gensound.h"
  31. #include "sounddep/sound.h"
  32. #include "events.h"
  33. #include "uae.h"
  34. #include "include/memory.h"
  35. #include "custom.h"
  36. #include "osdep/win32gui.h"
  37. #include "osdep/win32.h"
  38.  
  39. #define PRTBUFSIZE 1024
  40. UINT prttimer;
  41. char prtbuf[PRTBUFSIZE];
  42. int prtbufbytes;
  43. HANDLE hPrt = INVALID_HANDLE_VALUE;
  44. extern HWND hAmigaWnd;
  45.  
  46. void flushprtbuf (void)
  47. {
  48.     DWORD written;
  49.  
  50.     if (hPrt == INVALID_HANDLE_VALUE)
  51.     hPrt = CreateFile (prtname, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, NULL);
  52.     if (hPrt == INVALID_HANDLE_VALUE)
  53.     hPrt = CreateFile (prtname, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  54.  
  55.     if (hPrt != INVALID_HANDLE_VALUE)
  56.     WriteFile (hPrt, prtbuf, prtbufbytes, &written, 0);
  57.  
  58.     prtbufbytes = 0;
  59. }
  60.  
  61. void finishjob (void)
  62. {
  63.     flushprtbuf ();
  64.     if (hPrt != INVALID_HANDLE_VALUE) {
  65.     CloseHandle (hPrt);
  66.     hPrt = INVALID_HANDLE_VALUE;
  67.     }
  68.     KillTimer (hAmigaWnd, prttimer);
  69.     prttimer = 0;
  70. }
  71.  
  72. void putprinter (char val)
  73. {
  74.     PostMessage (hAmigaWnd, WM_USER + 0x200, val, 0);
  75. }
  76.  
  77. void DoSomeWeirdPrintingStuff (WPARAM wParam)
  78. {
  79.     if (prttimer)
  80.     KillTimer (hAmigaWnd, prttimer);
  81.     if (prtbufbytes < PRTBUFSIZE) {
  82.     prtbuf[prtbufbytes++] = wParam;
  83.     prttimer = SetTimer (hAmigaWnd, 1, 2000, NULL);
  84.     } else {
  85.     flushprtbuf ();
  86.     *prtbuf = wParam;
  87.     prtbufbytes = 1;
  88.     prttimer = 0;
  89.     }
  90. }
  91.  
  92. static HANDLE hCom = INVALID_HANDLE_VALUE;
  93. static HANDLE writeevent;
  94. static DCB dcb;
  95.  
  96. char inbuf[1024], outbuf[1024];
  97. int inptr, inlast, outlast;
  98.  
  99. int openser (char *sername)
  100. {
  101.     char buf[32];
  102.     COMMTIMEOUTS CommTimeOuts;
  103.  
  104.     sprintf (buf, "\\.\\\\%s", sername);
  105.  
  106.     if (!(writeevent = CreateEvent (NULL, TRUE, FALSE, NULL))) {
  107.     write_log ("Failed to create serial event!\n");
  108.     return 0;
  109.     }
  110.     if ((hCom = CreateFile (buf, GENERIC_READ | GENERIC_WRITE,
  111.                 0,
  112.                 NULL,
  113.                 OPEN_EXISTING,
  114.                 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
  115.                 NULL)) != INVALID_HANDLE_VALUE) {
  116.     SetCommMask (hCom, EV_RXFLAG);
  117.     SetupComm (hCom, 4096, 4096);
  118.     PurgeComm (hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
  119.     CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
  120.     CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
  121.     CommTimeOuts.ReadTotalTimeoutConstant = 0;
  122.     CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
  123.     CommTimeOuts.WriteTotalTimeoutConstant = 0;
  124.     SetCommTimeouts (hCom, &CommTimeOuts);
  125.  
  126.     GetCommState (hCom, &dcb);
  127.  
  128.     dcb.BaudRate = 9600;
  129.     dcb.ByteSize = 8;
  130.     dcb.Parity = 0;
  131.     dcb.StopBits = NOPARITY;
  132.  
  133.     dcb.fOutxCtsFlow = TRUE;
  134.     dcb.fOutxDsrFlow = FALSE;
  135.     dcb.fDtrControl = DTR_CONTROL_ENABLE;
  136.     dcb.fTXContinueOnXoff = FALSE;
  137.     dcb.fOutX = FALSE;
  138.     dcb.fInX = FALSE;
  139.     dcb.fNull = FALSE;
  140.     dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
  141.     dcb.fAbortOnError = FALSE;
  142.  
  143.     if (SetCommState (hCom, &dcb)) {
  144.         MyOutputDebugString ("Using %s\n", sername);
  145.         return 1;
  146.     }
  147.     CloseHandle (hCom);
  148.     hCom = INVALID_HANDLE_VALUE;
  149.     }
  150.     return 0;
  151. }
  152.  
  153. void closeser (void)
  154. {
  155.     if (hCom != INVALID_HANDLE_VALUE) {
  156.     CloseHandle (hCom);
  157.     hCom = INVALID_HANDLE_VALUE;
  158.     }
  159. }
  160.  
  161. void doserout (void)
  162. {
  163.     DWORD dwErrorFlags;
  164.     unsigned long actual;
  165.     OVERLAPPED ol =
  166.     {0};
  167.  
  168.     if (hCom != INVALID_HANDLE_VALUE) {
  169.     if (outlast) {
  170.         ResetEvent (ol.hEvent = writeevent);
  171.  
  172.         actual = 0;
  173.         if (!WriteFile (hCom, outbuf, outlast, &actual, &ol)) {
  174.         while (outlast -= actual) {
  175.             if ((dwErrorFlags = GetLastError ()) == ERROR_IO_INCOMPLETE || dwErrorFlags == ERROR_IO_PENDING) {
  176.             actual = 0;
  177.             GetOverlappedResult (hCom, &ol, &actual, FALSE);
  178.  
  179.             if ((dwErrorFlags = GetLastError ()) != ERROR_IO_INCOMPLETE && dwErrorFlags != ERROR_IO_PENDING) {
  180.                 MyOutputDebugString ("writeser: error %d, lost %d chars!\n", GetLastError (), outlast - actual);
  181.                 outlast = 0;
  182.                 break;
  183.             }
  184.             if (WaitForSingleObject (writeevent, 1000) == WAIT_TIMEOUT) {
  185.                 MyOutputDebugString ("writeser: timeout, lost %d chars!\n", outlast - actual);
  186.                 outlast = 0;
  187.                 break;
  188.             }
  189.             } else {
  190.             if (dwErrorFlags) {
  191.                 MyOutputDebugString ("writeser: error %d while writing, lost %d chars!\n", dwErrorFlags, outlast - actual);
  192.                 ClearCommError (hCom, &dwErrorFlags, NULL);
  193.             }
  194.             outlast = 0;
  195.             break;
  196.             }
  197.         }
  198.         }
  199.     }
  200.     } else {
  201.     outlast = 0;
  202.     inptr = inlast = 0;
  203.     }
  204. }
  205.  
  206. void writeser (char c)
  207. {
  208.     outbuf[outlast++] = c;
  209.     if (outlast == sizeof outbuf)
  210.     doserout ();
  211. }
  212.  
  213. int readser (char *buffer)
  214. {
  215.     COMSTAT ComStat;
  216.     DWORD dwErrorFlags;
  217.     DWORD result;
  218.     unsigned long actual;
  219.     OVERLAPPED ol =
  220.     {0};
  221.  
  222.     if (inptr < inlast) {
  223.     *buffer = inbuf[inptr++];
  224.     return 1;
  225.     }
  226.     if (hCom != INVALID_HANDLE_VALUE) {
  227.     inptr = inlast = 0;
  228.  
  229.     /* only try to read number of bytes in queue */
  230.     ClearCommError (hCom, &dwErrorFlags, &ComStat);
  231.     if (ComStat.cbInQue) {
  232.         if (!ReadFile (hCom, inbuf, min (ComStat.cbInQue, sizeof inbuf), &inlast, &ol)) {
  233.         if (GetLastError () == ERROR_IO_PENDING) {
  234.             write_log ("readser: INTERNAL ERROR - intermittent loss of serial data!\n");
  235.             for (;;) {
  236.             actual = 0;
  237.             result = GetOverlappedResult (hCom, &ol, &actual, TRUE);
  238.             inlast += actual;
  239.  
  240.             if (result)
  241.                 break;
  242.  
  243.             if (GetLastError () != ERROR_IO_INCOMPLETE) {
  244.                 ClearCommError (hCom, &dwErrorFlags, &ComStat);
  245.                 break;
  246.             }
  247.             }
  248.         } else
  249.             ClearCommError (hCom, &dwErrorFlags, &ComStat);
  250.         }
  251.     }
  252.     if (inptr < inlast) {
  253.         *buffer = inbuf[inptr++];
  254.         return 1;
  255.     }
  256.     }
  257.     return 0;
  258. }
  259.  
  260. void getserstat (int *status)
  261. {
  262.     DWORD stat;
  263.  
  264.     *status = 0;
  265.  
  266.     if (hCom != INVALID_HANDLE_VALUE) {
  267.     GetCommModemStatus (hCom, &stat);
  268. #if 0
  269.     /* ouch */
  270.     if (stat & MS_RLSD_ON)
  271.         *status |= TIOCM_CAR;
  272.     if (stat & MS_DSR_ON)
  273.         *status |= TIOCM_DSR;
  274. #endif
  275.     }
  276. }
  277.  
  278. int setbaud (long baud)
  279. {
  280.     if (hCom != INVALID_HANDLE_VALUE) {
  281.     if (GetCommState (hCom, &dcb)) {
  282.         dcb.BaudRate = baud;
  283.         if (!SetCommState (hCom, &dcb))
  284.         MyOutputDebugString ("Error setting baud rate %d!\n", baud);
  285.     } else
  286.         write_log ("setbaud: internal error!\n");
  287.     }
  288.     return 0;
  289. }
  290.  
  291.